/**
 * @program: clms-second
 * @description: 日志记录切面类
 * @author: mitu_echo
 * @create: 2021-07-26 16:38
 **/

package com.second.system.pojo.utils;

import com.second.common.pojo.R;
import com.second.common.util.JwtUtil;
import com.second.common.util.Payload;
import com.second.system.config.RsaKeyProperties;
import com.second.system.dao.LoginfoDao;
import com.second.system.pojo.entity.Loginfo;
import com.second.system.pojo.entity.User;
import com.second.system.service.LoginfoService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * 自定义切面类
 */
@Aspect
@Component
public class LoginfoAspect {

    @Resource
    private LoginfoDao loginfoDao;
    @Autowired
    private RsaKeyProperties rsaKeyProperties;

    /**
     * 设置切入点，为当前 系统下 service层
     */
    @Pointcut("execution( * com.second.system.service..*.*(..))")
    public void Pointcut() {
    }

    /**
     * @AfterReturning：后置
     * @param pjp
     * @return
     * @throws Throwable
     */
    @AfterReturning(value = "Pointcut()",returning="returnValue")
    public void AfterReturning(JoinPoint pjp,Object returnValue) throws Throwable {

        // 获取请求路径
        String uri = WebUtil.getRequest().getRequestURI();
        if ( !uri.contains("/login") ) {

            //获取目标类方法名称
            String methodName = pjp.getSignature().getDeclaringTypeName();
            // 获取参数列表
            Object[] args = pjp.getArgs();
            // 获取ip
            String ipAddr = IPUtils.getIpAddr(WebUtil.getRequest());
            // 获取token
            String token = WebUtil.getRequest().getHeader("Token");
            Payload<User> infoFromToken = JwtUtil.getInfoFromToken(token, rsaKeyProperties.getPublicKey(), User.class);
            User userInfo = infoFromToken.getUserInfo();

            // 执行日志表的新增方法，将所有操作加入到日志表中
            Loginfo loginfo = new Loginfo();
            // 从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            // 获取切入点所在的方法
            Method method = signature.getMethod();
            // 获取自定义注解
            MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
            if (myAnnotation != null) {
                loginfo.setTitle(myAnnotation.title());
                loginfo.setBusinessType(myAnnotation.businessType());
            }
            loginfo.setMethod(methodName);
            loginfo.setOperatorType(1);
            loginfo.setOperName(userInfo.getLoginname());
            loginfo.setOperUrl(uri);
            loginfo.setIpaddr(ipAddr);
            loginfo.setOperLocation("内网ip");
            loginfo.setOperTime(LocalDateTime.now().toString());
            loginfo.setOperParam(Arrays.toString(args));
            if (returnValue != null) {
                R r = (R) returnValue;
                if ( r.getCode() == 200) {
                    loginfo.setStatus(0);
                } else {
                    loginfo.setStatus(1);
                    loginfo.setErrorMsg(r.getMessage());
                }
            }
            loginfoDao.insert(loginfo);
        }
    }

}
